package com.banshuibao.bsb_android.download;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.banshuibao.bsb_android.R;
import com.banshuibao.bsb_android.adapter.DownloadViewAdapter;
import com.banshuibao.bsb_android.fragment.BaseFragment;
import com.banshuibao.bsb_android.model.DownloadInfo;
import com.banshuibao.bsb_android.util.CCMediaConfig;
import com.banshuibao.bsb_android.util.DataSet;
import com.banshuibao.bsb_android.util.MediaUtil;
import com.banshuibao.bsb_android.util.ParamsUtil;
import com.bokecc.sdk.mobile.download.Downloader;
import com.bokecc.sdk.mobile.exception.ErrorCode;

/**
 * 下载中标签页
 *
 * @author CC视频
 */
public class DownloadingFragment extends BaseFragment {

    private Context context;
    private FragmentActivity activity;

    private DownloadService.DownloadBinder binder;
    private ServiceConnection serviceConnection;
    private ListView downloadingListView;
    private List<DownloadInfo> downloadingInfos;
    private DownloadViewAdapter downloadAdapter;

    private Timer timter = new Timer();
    private boolean isBind;
    private Intent service;
    private DownloadedReceiver receiver;
    private String currentDownloadTitle;
    private LinearLayout bottomLayout;
    private TextView all, delete;
    private HashMap<String, String> deletes;
    private TextView menu;
    private boolean isCheckModel;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        activity = getActivity();
        context = activity.getApplicationContext();
        bindServer();
        timter.schedule(timerTask, 0, 1000);
        receiver = new DownloadedReceiver();
        activity.registerReceiver(receiver, new IntentFilter(CCMediaConfig.ACTION_DOWNLOADING));
        return LayoutInflater.from(activity).inflate(R.layout
                .fragment_downloading, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        initView(view);
        updateData();
    }

    private void bindServer() {
        service = new Intent(context, DownloadService.class);
        serviceConnection = new ServiceConnection() {
            @Override
            public void onServiceDisconnected(ComponentName name) {
                Log.i("service disconnected", name + "");
            }

            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                binder = (DownloadService.DownloadBinder) service;
            }
        };
        activity.bindService(service, serviceConnection,
                Context.BIND_AUTO_CREATE);
    }

    private void initView(View view) {
        downloadingListView = view.findViewById(R.id.listView);
        downloadingListView.setDivider(null);
        bottomLayout = view.findViewById(R.id.bottom_layout);
        all = view.findViewById(R.id.all);
        delete = view.findViewById(R.id.delete);
        downloadAdapter = new DownloadViewAdapter(context);
        downloadingListView.setAdapter(downloadAdapter);
        menu = activity.findViewById(R.id.menu);
        menu.setOnClickListener(l);
        all.setOnClickListener(l);
        delete.setOnClickListener(l);

        deletes = new HashMap<>();
        downloadingListView.setOnItemClickListener(onItemClickListener);
    }

    private void updateData() {
        if (downloadingInfos != null) {
            downloadingInfos.clear();
        } else {
            downloadingInfos = new ArrayList<>();
        }
        List<DownloadInfo> downloadInfos = DataSet.getDownloadInfos();
        for (DownloadInfo downloadInfo : downloadInfos) {

            if (downloadInfo.getStatus() == Downloader.FINISH) {
                continue;
            }

            if ((downloadInfo.getStatus() == Downloader.DOWNLOAD) && (binder == null || binder.isStop())) {
                Intent service = new Intent(context, DownloadService.class);
                service.putExtra("title", downloadInfo.getVideoId());
                activity.startService(service);
            }
            downloadingInfos.add(downloadInfo);
        }
        downloadAdapter.setPairs(downloadingInfos);
    }


    private OnItemClickListener onItemClickListener = new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            if (downloadAdapter == null)
                return;
            DownloadInfo downloadInfo = downloadAdapter.getItem(position);
            if (isCheckModel) {
                downloadInfo.setCheck(!downloadInfo.isCheck());
                if (downloadInfo.isCheck())
                    deletes.put(downloadInfo.getTitle(), downloadInfo.getVideoId());
                else
                    deletes.remove(downloadInfo.getTitle());
                updateDeletesText();
                downloadAdapter.notifyDataSetChanged();
            } else {
                //若下载任务已停止，则下载新数据
                if (binder.isStop()) {
                    Intent service = new Intent(context, DownloadService.class);
                    service.putExtra("title", downloadInfo.getVideoId());
                    activity.startService(service);
                    currentDownloadTitle = downloadInfo.getVideoId();

                } else if (downloadInfo.getTitle().equals(currentDownloadTitle)) {
                    switch (binder.getDownloadStatus()) {
                        case Downloader.PAUSE:
                            binder.download();
                            break;
                        case Downloader.DOWNLOAD:
                            binder.pause();
                            break;
                    }
                }
            }
        }
    };

    private View.OnClickListener l = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.all:
                    int listSize = downloadAdapter.getList().size();
                    if (listSize == 0)
                        return;
                    int deleteSize = deletes.size();
                    if (deleteSize >= listSize) {
                        for (int i = 0; i < listSize; ++i) {
                            downloadAdapter.getList().get(i).setCheck(false);
                        }
                        deletes.clear();
                    } else {
                        for (int i = 0; i < listSize; ++i) {
                            DownloadInfo downloadInfo = downloadAdapter.getList().get(i);
                            downloadInfo.setCheck(true);
                            deletes.put(downloadInfo.getTitle(), downloadInfo.getVideoId());
                        }
                    }
                    updateDeletesText();
                    downloadAdapter.notifyDataSetChanged();
                    break;
                case R.id.delete:
                    if (deletes.size() == 0) {
                        return;
                    }
                    for (HashMap.Entry<String, String> entry : deletes.entrySet()) {
                        delete(entry.getValue());
                    }
                    deletes.clear();
                    updateDeletesText();
                    downloadAdapter.notifyDataSetChanged();
                    break;
                case R.id.menu:
                    setCheckModel();
                    break;
            }
        }
    };

    public void setCheckModel() {
        if (isHidden())
            return;
        isCheckModel = !isCheckModel;
        if (isCheckModel) {
            bottomLayout.setVisibility(View.VISIBLE);
            menu.setText("取消");
        } else {
            menu.setText("管理");
            setClearDelete();
        }
        downloadAdapter.setShowCheck(isCheckModel);
    }

    private void setClearDelete() {
        bottomLayout.setVisibility(View.GONE);
        menu.setText("管理");
        isCheckModel = false;
        int size = downloadAdapter.getList().size();
        for (int i = 0; i < size; ++i) {
            downloadAdapter.getList().get(i).setCheck(false);
        }
        deletes.clear();
        updateDeletesText();
        downloadAdapter.setShowCheck(isCheckModel);
    }

    private void updateDeletesText() {
        delete.setText(String.valueOf("删除" + "(" + deletes.size() + ")"));
    }

    private void delete(String videoId) {
        DataSet.removeDownloadInfo(videoId);
        File file = MediaUtil.getMediaFile(CCMediaConfig.DOWNLOAD_DIR, videoId);
        if (file.exists()) {
            file.delete();
        }
        if (TextUtils.isEmpty(currentDownloadTitle))
            currentDownloadTitle = binder.getTitle();
        // 通知service取消下载
        if (!binder.isStop() && videoId.equals(currentDownloadTitle)) {
            binder.cancel();
            startWaitStatusDownload();
        }

        updateData();
    }

    private Handler handler = new Handler() {

        private int currentPosition = ParamsUtil.INVALID;
        private int currentProgress = 0;

        @Override
        public void handleMessage(Message msg) {

            String title = (String) msg.obj;

            if (title == null || downloadingInfos.isEmpty()) {
                return;
            }

            resetHandlingTitle(title);

            int progress = binder.getProgress();
            if (progress > 0 && currentPosition != ParamsUtil.INVALID) {

                if (currentProgress == progress) {
                    return;
                }
                currentProgress = progress;
                DownloadInfo downloadInfo = downloadingInfos.remove(currentPosition);

                downloadInfo.setProgress(binder.getProgress());
                downloadInfo.setProgressText(binder.getProgressText());
                DataSet.updateDownloadInfo(downloadInfo);

                downloadingInfos.add(currentPosition, downloadInfo);
                downloadAdapter.notifyDataSetChanged();
                downloadingListView.invalidate();

            }

            super.handleMessage(msg);
        }

        private void resetHandlingTitle(String title) {
            for (DownloadInfo d : downloadingInfos) {
                if (TextUtils.equals(d.getTitle(), title)) {
                    currentPosition = downloadingInfos.indexOf(d);
                    break;
                }
            }
        }

    };

    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        if (!isHidden()) {
            if (getActivity() != null) {
                menu = getActivity().findViewById(R.id.menu);
                menu.setOnClickListener(l);
            }
        }
        if (hidden) {
            setClearDelete();
        }
    }

    // 通过定时器和Handler来更新进度条
    private TimerTask timerTask = new TimerTask() {
        @Override
        public void run() {

            if (binder == null || binder.isStop()) {
                return;
            }

            // 判断是否存在正在下载的视频
            if (currentDownloadTitle == null) {
                currentDownloadTitle = binder.getTitle();
            }

            if (currentDownloadTitle == null || downloadingInfos.isEmpty()) {
                return;
            }

            Message msg = new Message();
            msg.obj = currentDownloadTitle;

            handler.sendMessage(msg);
        }
    };

    @Override
    public void onDestroy() {
        activity.unbindService(serviceConnection);
        activity.unregisterReceiver(receiver);
        timerTask.cancel();
        isBind = false;
        if (downloadAdapter != null) {
            downloadAdapter.clear();
            downloadAdapter = null;
        }
        super.onDestroy();
    }

    private class DownloadedReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {

            if (isBind) {
                bindServer();
            }

            if (intent.getStringExtra("title") != null) {
                currentDownloadTitle = intent.getStringExtra("title");
            }

            int downloadStatus = intent.getIntExtra("status", ParamsUtil.INVALID);
            // 若当前状态为下载中，则重置view的标记位置
            if (downloadStatus == Downloader.DOWNLOAD) {
                currentDownloadTitle = null;
            }

            updateData();
            downloadAdapter.notifyDataSetChanged();
            downloadingListView.invalidate();

            // 若当前状态为下载完成，且下载队列不为空，则启动service下载其他视频
            if (downloadStatus == Downloader.FINISH) {

                if (!downloadingInfos.isEmpty()) {
                    startWaitStatusDownload();
                }
            }

            // 若下载出现异常，提示用户处理
            int errorCode = intent.getIntExtra("errorCode", ParamsUtil.INVALID);
            if (errorCode == ErrorCode.NETWORK_ERROR.Value()) {
                Toast.makeText(context, "网络异常，请检查", Toast.LENGTH_SHORT).show();
            } else if (errorCode == ErrorCode.PROCESS_FAIL.Value()) {
                Toast.makeText(context, "下载失败，请重试", Toast.LENGTH_SHORT).show();
            } else if (errorCode == ErrorCode.INVALID_REQUEST.Value()) {
                Toast.makeText(context, "下载失败，请检查帐户信息", Toast.LENGTH_SHORT)
                        .show();
            }
        }
    }

    private void startWaitStatusDownload() {
        for (DownloadInfo downloadInfo : downloadingInfos) {
            if (downloadInfo.getStatus() == Downloader.WAIT) {
                currentDownloadTitle = downloadInfo.getTitle();
                Intent service = new Intent(context, DownloadService.class);
                service.putExtra("title", currentDownloadTitle);
                activity.startService(service);
                break;
            }
        }
    }

}
